cmake_minimum_required(VERSION 3.10)

# 是否编译arm平台
option(BUILD_ARM "Build the platform arm" OFF)

# 设置不同平台的编译参数

if(WIN32)
    # 设置windows下的gcc工具
    set(tools "F:/SsdSofawareInstall/QT5/Tools/mingw730_64")
    set(CMAKE_C_COMPILER ${tools}/bin/gcc.exe)
    set(CMAKE_CXX_COMPILER ${tools}/bin/g++.exe)
    set(CMAKE_SYSTEM_NAME Windows)

    # windows下编译
    # cmake -G "MinGW Makefiles" .. && /f/SsdSofawareInstall/QT5/Tools/mingw730_64/bin/mingw32-make.exe -j32
elseif(UNIX)
    # 设置平台信息
    set(CMAKE_SYSTEM_NAME Linux)

    # 是否交叉编译
    if(BUILD_ARM)
        set(CMAKE_SYSTEM_PROCESSOR arm)
        set(tools /home/mat/workspace/Board/jz2440/cross_compatel/4.4.3)
        set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gcc)
        set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-g++)
    else()
        message(STATUS "build linux x86")
    endif()

elseif(APPLE)
    set(CMAKE_SYSTEM_NAME Apple)
endif()

# 工程的名字
project(usb_mouse LANGUAGES C CXX)

# 定义CMAKE_BUILD_TYPE变量
# Debug:调试模式，完全不优化，生成调试信息，方便调试程序
# Release:发布模式，优化程度最高，性能最佳，但是编译比 Debug 慢
# MinSizeRel:最小体积发布，生成的文件比 Release 更小，不完全优化，减少二进制体积
# RelWithDebInfo:带调试信息发布，生成的文件比 Release 更大，因为带有调试的符号信息
# 这是为了让用户在使用程序出错时，能够反馈一些信息。
set(CMAKE_BUILD_TYPE Debug)

# 设置生成compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS True)

# 设置版本号
set(${PROJECT_NAME}_MAJOR "1")
set(${PROJECT_NAME}_MINOR "0")
set(${PROJECT_NAME}_PATCH "0")

# 设置是否编译动态库
option(BUILD_SHARED_LIBS "Build the project shared library" ON)

# 打包时cpack使用相对路径,不打包时使用OFF
option(WPACK "Cmake Pack can't use local path" ON)

if(WPACK)
    set(EXEC_INSTALL_BIN bin)
    set(EXEC_INSTALL_LIB lib)
endif()

# 设置CMAKE_MODULE位置
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")

# 设置编译的参数版本
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)

# 设置编译的参数版本
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 设置程序输出编译的位置
# .a .lib静态库位置
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/install")
# .dll exe 可执行文件位置
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/install")
# .so 库位置
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/install")

# 设置工程包含当前目录
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 收集子目录中对应的类型文件到某个全局属性中最终编译出程序
function(add_file list)
    # 如果定义了不重新定义
    get_property(is_defined GLOBAL PROPERTY ${list} DEFINED)
    if(NOT is_defined)
        define_property(GLOBAL PROPERTY ${list}
                BRIEF_DOCS "List of source files"
                FULL_DOCS "List of source files to be compiled in one library")
    endif()
    set(SRCS)
    foreach(S IN LISTS ARGN)
        # message(STATUS "${S}")
        list(APPEND SRCS "${S}")
    endforeach()
    # 添加到全局列表
    # message(${SRCS})
    set_property(GLOBAL APPEND PROPERTY ${list} "${SRCS}")
    # message(STATUS "${list}")
endfunction()

# 通过find_package查找需要依赖的包

# 查找交叉编译的make install的libusb库
# 假设安装在${${PROJECT_SOURCE_DIR}/libs/libusb}
# list(APPEND CMAKE_PREFIX_PATH ${${PROJECT_SOURCE_DIR}/libs/libusb})

# 不同的平台设置find_library的查找参数
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
    SET(CMAKE_FIND_LIBRARY_PREFIXES "")
    SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll")
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
    SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
    SET(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
endif()

# FindLibUsb.cmake例子
# 查找libusb库
# 和"FindLibusb.cmake"对应
find_package(Libusb REQUIRED)
# 包含libusb头文件
include_directories(${LIBUSB_INCLUDE_DIRS})
# 链接libusb库
link_libraries(${LIBUSB_LIBRARIES})

# 连接一些三方库
add_subdirectory(libs)

# 添加子目录
add_subdirectory(src)

# PACK时不需要doxygen文档
if (NOT WPACK)
    # Doxygen 生成文档
    include(BuildDoxygen)
    # make docs生成文档
endif()

# uninstall target 卸载命令
# https://cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
    IMMEDIATE @ONLY)
add_custom_target(uninstall
    ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)

# 添加自定义命令
# make uninstall
# add_custom_target("uninstall" COMMENT "Uninstall installed files")
# add_custom_command(
#     TARGET "uninstall"
#     POST_BUILD
#     COMMENT "Uninstall files with install_manifest.txt"
#     COMMAND xargs rm -vf < install_manifest.txt || echo Nothing in
#             install_manifest.txt to be uninstalled!
# )

# 打包成安装程序
if(WPACK)
    include(InstallRequiredSystemLibraries)

    set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) # 声明包的名称
    # set(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}\\\\gqrx.ico) # 无作用
    # set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) # 带有安装说明的纯文本文件
    # set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hello") # 包的描述
    set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE) # 许可证文件
    # CPack所需的主要、次要和补丁版本
    set(CPACK_PACKAGE_VERSION_MAJOR ${${PROJECT_NAME}_MAJOR})
    set(CPACK_PACKAGE_VERSION_MINOR ${${PROJECT_NAME}_MINOR})
    set(CPACK_PACKAGE_VERSION_PATCH ${${PROJECT_NAME}_PATCH})

    set(CPACK_PACKAGE_DESCRIPTION "Matace") # 声明包的供应商
    # 设置了在包装的时候需要忽略的文件列表和目录
    # set(CPACK_SOURCE_IGNORE_FILES "${PROJECT_BINARY_DIR};/.git/;.gitignore")
    # ZIP,用于生成.ZIP TGZ用于.tar.gz
    set(CPACK_SOURCE_GENERATOR "ZIP;TGZ")
    # 二进制存档生成器
    set(CPACK_GENERATOR "ZIP;TGZ")

    if(CMAKE_SYSTEM_NAME MATCHES "Linux")

        list(APPEND CPACK_GENERATOR "DEB") # 生成DEB包
        set(CPACK_DEBIAN_PACKAGE_MAINTAINER "robertodr")
        set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
        set(CPACK_DEBIAN_PACKAGE_DEPENDS "uuid-dev")
        
        list(APPEND CPACK_GENERATOR "RPM")
        set(CPACK_RPM_PACKAGE_RELEASE "1")
        set(CPACK_RPM_PACKAGE_LICENSE "MIT")
        set(CPACK_RPM_PACKAGE_REQUIRES "uuid-devel")

    elseif(CMAKE_SYSTEM_NAME MATCHES "Windows")

        list(APPEND CPACK_GENERATOR "NSIS")
        set(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME}") # 安装程序顶部显示的标题
        set(CPACK_NSIS_CONTACT "angelo@com") # 有关安装过程的问题和意见的联系信息
        # NSIS 安装程序向最终用户提供的默认安装目录位于此根目录下。呈现给最终用户的完整目录是：${CPACK_NSIS_INSTALL_ROOT}/${CPACK_PACKAGE_INSTALL_DIRECTORY}
        # set(CPACK_NSIS_INSTALL_ROOT "C:/Program Files")
        # set(CPACK_PACKAGE_INSTALL_DIRECTORY "MyPackage") # 包的默认安装路径
        # 包含安装程序图标的可执行文件的路径
        # set(CPACK_NSIS_INSTALLER_ICON_FILE bin\\\\${PROJECT_NAME}.exe)
        set(CPACK_NSIS_MUI_ICON ${CMAKE_SOURCE_DIR}/gqrx.ico)  # 用作生成的安装程序的主图标
        set(CPACK_NSIS_MUI_UNIICON ${CMAKE_SOURCE_DIR}/gqrx.ico) # 用作生成的卸载程序的主图标
        # 修改 PATH 开关。如果设置为 ON，那么安装程序中将出现一个额外的页面，允许用户选择是否应将程序目录添加到系统PATH变量中
        set(CPACK_NSIS_MODIFY_PATH ON)
        # 询问是否先卸载以前的版本。如果设置为“ON”，则安装程序将查找以前安装的版本，如果找到，询问用户是否在继续安装之前将其卸载
        set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
        # Windows 的“控制面板”中的“应用程序和功能”中出现的显示名称字符串
        set(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME}")
        # 提供安装应用程序帮助的网站的 URL
        set(CPACK_NSIS_HELP_LINK http://www.matace.com)
        # 提供有关您的应用程序的更多信息的网站的 URL
        set(CPACK_NSIS_URL_INFO_ABOUT http://www.example.com)
        # 用于创建“开始菜单”快捷方式的其他 NSIS 命令
        # CPACK_NSIS_CREATE_ICONS_EXTRA
        # 用于卸载“开始菜单”快捷方式的其他 NSIS 命令
        # CPACK_NSIS_DELETE_ICONS_EXTRA
        # 创建 NSIS Start Menu 链接假定它们在 bin 中，除非设置了这个变量。例如，如果您的可执行文件位于 exec 目录中，您可以将其设置为 exec
        # CPACK_NSIS_EXECUTABLES_DIRECTORY
        # 指定一个可执行文件以添加一个选项以在 NSIS 安装程序的完成页面上运行
        # CPACK_NSIS_MUI_FINISHPAGE_RUN
        # set(CPACK_NSIS_INSTALLER_MUI_FILE ${CMAKE_CURRENT_SOURCE_DIR}/mycustom.nsi) # 使用自定义NSIS配置模板

    endif()

    include(CPack)

endif()

# -S 指定源码所在的文件夹
# -B 指定生成目录
# -G 指定构建工具
# cmake -S . -B build -G "MinGW Makefiles" && cmake --build build && cd build && cpack.exe .\CPackConfig.cmake

